﻿#include "baiduspeech.h"
#include <QUrlQuery>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QHostInfo>
#include <QDebug>

BaiduSpeech::BaiduSpeech(QObject *parent) :
    QObject(parent)
{
    asr_client = new QNetworkAccessManager(this);
    connect(asr_client, &QNetworkAccessManager::finished, this, &BaiduSpeech::on_ASRReply);

    tts_client = new QNetworkAccessManager(this);
    connect(tts_client, &QNetworkAccessManager::finished, this, &BaiduSpeech::on_TTSReply);
}

void BaiduSpeech::doASR(const QByteArray data)
{
    QJsonObject root;
    root["format"] = "wav"; //语音文件的格式
    root["rate"] = 16000;   //采样率
    root["channel"] = 1;    //声道数
    root["cuid"] = QHostInfo::localHostName(); //用户唯一标识，这里使用主机名
    root["token"] = _token;
    root["dev_pid"] = 80001; //极速版输入法模型
    root["speech"] = QString(data.toBase64()); //语音数据
    root["len"] = data.length(); //语音文件的的字节数

    QUrl api("https://vop.baidu.com/pro_api");
    QNetworkRequest request(api);
    request.setRawHeader("Content-Type", "application/json");

    asr_client->post(request, QJsonDocument(root).toJson());
}

void BaiduSpeech::on_ASRReply(QNetworkReply* reply)
{
    QJsonDocument json = QJsonDocument::fromJson(reply->readAll());

    int err_no = json["err_no"].toInt();

    if (err_no) {
        _text = json["err_msg"].toString();
    }
    else {
        _text = "";
        foreach (const QJsonValue &i, json["result"].toArray()) {
            _text += i.toString();
        }
    }

    reply->deleteLater();
    emit doneASR(err_no);
}

void BaiduSpeech::doTTS(const QString data)
{
    QUrlQuery params;
    params.addQueryItem("tex", data.toUtf8().toPercentEncoding()); //合成的文本，需要2次URL编码
    params.addQueryItem("tok", _token);
    params.addQueryItem("cuid", QHostInfo::localHostName()); //用户唯一标识
    params.addQueryItem("ctp", "1"); //客户端类型选择，web端填写固定值1
    params.addQueryItem("lan", "zh");//语言选择,目前只有中英文混合模式，填写固定值zh
    params.addQueryItem("aue", "4"); //QAudioOutput 需要使用PCM 16K
    params.addQueryItem("spd", "5"); //语速0~15，默认5
    params.addQueryItem("pit", "5"); //音调0~15，默认5
    params.addQueryItem("vol", "5"); //音量0~15，默认5
    params.addQueryItem("per", "4"); //音库：度小宇=1，度小美=0，度逍遥=3，度丫丫=4

    QNetworkRequest request(QUrl("https://tsn.baidu.com/text2audio"));
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");

    tts_client->post(request, params.toString(QUrl::FullyEncoded).toUtf8());
}

void BaiduSpeech::on_TTSReply(QNetworkReply* reply)
{
    //根据 Content-Type的头部来确定是否服务端合成成功
    //如果合成成功，返回的Content-Type以“audio”开头
    //如果合成出现错误，则会返回json文本
    QString ctype = reply->rawHeader("Content-Type");
    if (ctype.startsWith("audio"))
    {
        _audio = reply->readAll();
        emit doneTTS(0); //完成信号中带错误码
    }
    else
    {
        QJsonDocument json = QJsonDocument::fromJson(reply->readAll());
        _text = json["err_msg"].toString();
        emit doneTTS(json["err_no"].toInt());
    }

    reply->deleteLater();
}

QString BaiduSpeech::text()
{
    return _text;
}

QByteArray BaiduSpeech::audio()
{
    return _audio;
}
